package edu.calpoly.android.echoes;

import java.util.HashMap;

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;

public class AudioPlayer {
	
	private Context m_context;
	private SoundPool m_soundPool;
	private HashMap<Integer, Integer> m_soundPoolMap;
	private AudioManager m_audioManager;
	
	private static final int MAX_SOUND_STREAMS = 8;
	private static final float MAX_PLAYBACK_RATE = 2.0f;
	private static final float MIN_PLAYBACK_RATE = 0.5f;
	
	private static final int PLAY_TEST_SOUND = 1;
	
	//Latin Percussion Chord
	protected static final int LATIN_CHORD = 2;
	private static final int PLAY_LATIN_SOUND1 = LATIN_CHORD + 0;
	private static final int PLAY_LATIN_SOUND2 = LATIN_CHORD + 1;
	private static final int PLAY_LATIN_SOUND3 = LATIN_CHORD + 2;
	private static final int PLAY_LATIN_SOUND4 = LATIN_CHORD + 3;
	private static final int PLAY_LATIN_SOUND5 = LATIN_CHORD + 4;
	private static final int PLAY_LATIN_SOUND6 = LATIN_CHORD + 5;
	private static final int PLAY_LATIN_SOUND7 = LATIN_CHORD + 6;
	private static final int PLAY_LATIN_SOUND8 = LATIN_CHORD + 7;
	
	//Piano Chord
	protected static final int PIANO_CHORD = 10;
	private static final int PLAY_PIANO_SOUND1 = PIANO_CHORD + 0;
	private static final int PLAY_PIANO_SOUND2 = PIANO_CHORD + 1;
	private static final int PLAY_PIANO_SOUND3 = PIANO_CHORD + 2;
	private static final int PLAY_PIANO_SOUND4 = PIANO_CHORD + 3;
	private static final int PLAY_PIANO_SOUND5 = PIANO_CHORD + 4;
	private static final int PLAY_PIANO_SOUND6 = PIANO_CHORD + 5;
	private static final int PLAY_PIANO_SOUND7 = PIANO_CHORD + 6;
	private static final int PLAY_PIANO_SOUND8 = PIANO_CHORD + 7;
	
	private int chord = 1;
	
	
	public AudioPlayer(Context context) {
		m_context = context;
		initSoundManagement();
		initSounds();
	}
	
	public void initSounds() {
		addSound(PLAY_TEST_SOUND, R.raw.bell);
		
		addSound(PLAY_LATIN_SOUND1, R.raw.latinpercussion1);
		addSound(PLAY_LATIN_SOUND2, R.raw.latinpercussion2);
		addSound(PLAY_LATIN_SOUND3, R.raw.latinpercussion3);
		addSound(PLAY_LATIN_SOUND4, R.raw.latinpercussion4);
		addSound(PLAY_LATIN_SOUND5, R.raw.latinpercussion5);
		addSound(PLAY_LATIN_SOUND6, R.raw.latinpercussion6);
		addSound(PLAY_LATIN_SOUND7, R.raw.latinpercussion7);
		addSound(PLAY_LATIN_SOUND8, R.raw.latinpercussion8);
		
		addSound(PLAY_PIANO_SOUND1, R.raw.piano1);
		addSound(PLAY_PIANO_SOUND2, R.raw.piano2);
		addSound(PLAY_PIANO_SOUND3, R.raw.piano3);
		addSound(PLAY_PIANO_SOUND4, R.raw.piano4);
		addSound(PLAY_PIANO_SOUND5, R.raw.piano5);
		addSound(PLAY_PIANO_SOUND6, R.raw.piano6);
		addSound(PLAY_PIANO_SOUND7, R.raw.piano7);
		addSound(PLAY_PIANO_SOUND8, R.raw.piano8);
	}

	/**
	 * Initializes the context for the player, a new SoundPool, a 
	 * HashMap to store references to the audio clips, and the 
	 * AudioManager
	 */
	public void initSoundManagement() {
		m_soundPool = new SoundPool(MAX_SOUND_STREAMS, AudioManager.STREAM_MUSIC, 0);
	    m_soundPoolMap = new HashMap<Integer, Integer>();
	    m_audioManager = (AudioManager)m_context.getSystemService(Context.AUDIO_SERVICE);
	}
	
	/**
	 * Store a new audio clip
	 * @param index		An unused index to reference the song
	 * @param SoundID	The ID of the clip from the automatically
	 * generated R file
	 */
	public void addSound(int index, int SoundID)
	{
	    m_soundPoolMap.put(index, m_soundPool.load(m_context, SoundID, 1));
	}
	
	/**
	 * Play an audio clip once
	 * @param index	The reference number used to store the clip
	 * @param freq	frequency of the provided audio clip to use
	 * upper limit of 2.0f, lower limit of 0.5f
	 */
	public void playSound(int index, float freq)
	{
		Log.e("playSound", "attempting to play " + index);
		if(freq <= MAX_PLAYBACK_RATE && freq >= MIN_PLAYBACK_RATE) {
			float streamVolume = m_audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
			streamVolume = streamVolume / m_audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		    m_soundPool.play(m_soundPoolMap.get(index), streamVolume, streamVolume, 1, 0, freq);
		}
	}
	
	/**
	 * Plays an audio clip repeatedly
	 * @param index	The reference number used to store the clip
	 * @param freq	frequency of the provided audio clip to use
	 * upper limit of 2.0f, lower limit of 0.5f
	 */
	public void playLoopedSound(int index, float freq)
	{
		if(freq <= MAX_PLAYBACK_RATE && freq >= MIN_PLAYBACK_RATE) {
		    int streamVolume = m_audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
		    streamVolume = streamVolume / m_audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		    m_soundPool.play(m_soundPoolMap.get(index), streamVolume, streamVolume, 1, -1, freq);
		}    
	}
}
